/*
 * @Author: zhangyang
 * @Date: 2022-03-01 19:40:13
 * @LastEditTime: 2022-03-08 15:56:39
 * @Description: 权限校验
 */
import { router } from './1-router';
import type { NavArrItem, UserModule } from '@/typings/type';
import type { RouteLocationNormalized } from 'vue-router';
import { getToken, TopIndex, useNavStore, useTagsStore, useUserStore } from '@/stores';
import { getUserInfo } from '@/api/user';

const changeTitle = (route: RouteLocationNormalized) => {
  document.title = route.meta.title || import.meta.env.VITE_TITLE || '小黑后台';
};

let role_route: string[] = [];
const generateRoleRoute = (arr: NavArrItem[], num?: number): string[] => {
  if (num === 1) {
    role_route = [];
  }
  for (const item of arr) {
    item.node_path && role_route.push(item.node_path);
    // 子节点递归遍历
    if (Array.isArray(item.part) && item.part.length > 0) {
      const part = JSON.parse(JSON.stringify(item.part));
      // 尾递归优化
      generateRoleRoute(part);
    }
  }
  return role_route;
};

export const generateNavData = async () => {
  const info = await getUserInfo();
  const {
    admin_name,
    real_name,
    role_id,
    role_name,
    is_enable,
    autoid,
    phone_number,
    menuBar
  } = info;
  const { UserInfo } = storeToRefs(useUserStore());
  const { NavArr, LeftNav, RoleRoute } = storeToRefs(useNavStore());
  UserInfo.value = {
    admin_name,
    autoid,
    real_name,
    role_id,
    role_name: Array.isArray(role_name) ? role_name : [role_name],
    is_enable,
    tel: phone_number || ''
  };
  // 后端获取用户可见节点
  const navArr: NavArrItem[] = menuBar;
  const routes: string[] = generateRoleRoute(navArr, 1);
  
  // 导航数组
  NavArr.value = navArr.slice();
  const top = navArr.find((item) => item.autoid === TopIndex.value);
  LeftNav.value = top?.part ?? [];
  // 生成角色有权访问的路由
  RoleRoute.value = routes.slice();
};

export const hasPermission = (path: string) => {
  const { RoleRoute } = storeToRefs(useNavStore());

  const roleRoute = RoleRoute.value;
  return roleRoute.includes(path);
};

export const install: UserModule = (app) => {
  router.beforeEach(async (to, from, next) => {
    // 开始进度条
    window.$loadingBar.start();
    // 重新生成权限数据
    const { NavArr } = useNavStore();
    // 没有导航数据，或者首次登录，需要重新生成权限数组
    getToken().token && (NavArr.length === 0 || from.name === 'base-login') && await generateNavData();

    if (to.meta.authPath === undefined || hasPermission(to.meta.authPath)) {
      // 无权限页面或者需要鉴权但拥有权限
      changeTitle(to);
      next();
    } else if (!getToken().token) {
      // 拥有权限验证，但是未登录
      await new Promise((resolve) => {
        window.$alert.error({
          title: '提示',
          content: '请先登录之后再继续操作',
          'positive-text': '确认',
          closable: false,
          'mask-closable': false,
          'onPositiveClick': () => resolve(true)
        });
      });
      next({
        name: 'base-login',
        query: {
          redirect: to.path
        }
      });
    } else {
      // 无权限
      next({ name: '403' });
      window.$loadingBar.error();
    }
  });

  router.afterEach((to) => {
    const { addView } = useTagsStore();
    addView(to);
    window.$loadingBar.finish();
  });
};
